#include <sstream>
#include "Parser.h"

#define CG_ANNOTATE_SEPARATOR "--------------------------------------------------------------------------------"

using namespace std;

Parser::Parser() : dr(0), dw(0), d1mr(0), d1mw(0), dr_ciclo(0), dw_ciclo(0), d1mr_ciclo(0), d1mw_ciclo(0) {

}
void Parser::parsear(const string& filename, const string& funcion) {

  std::fstream archivo;
  archivo.open(filename.c_str(), std::fstream::in);

  string linea;
  int seccion = 0;
  while (getline(archivo, linea)) {
    if (linea.compare(CG_ANNOTATE_SEPARATOR) == 0) {
      ++seccion;
    //valores globales
    } else if (funcion.compare("") == 0  && seccion == 3) {
      parse_line(linea);
    //valores para una funcion en particular
    } else if (funcion.compare("") != 0 && seccion == 5) {
      string funcion_actual(linea.substr(linea.rfind(':') + 1, funcion.size()));
      if (funcion.compare(funcion_actual) == 0) {
        parse_line(linea);
      }
    } else if (seccion == 9 || seccion == 7) {
      if (linea.find("memoria[i*tamanioCache]= '1';") != string::npos) {
        stringstream buffer(linea);
        string dr, dw, d1mr, d1mw;
        buffer >> dr;
        buffer >> dw;
        buffer >> d1mr;
        buffer >> d1mw;

        this->dr_ciclo = to_int(dr);
        this->dw_ciclo = to_int(dw);
        this->d1mr_ciclo = to_int(d1mr);
        this->d1mw_ciclo = to_int(d1mw);
      }
    } 
  }

  archivo.close();
}

void Parser::parse_line(const string& line) {
  stringstream buffer(line);
  string dr, dw, d1mr, d1mw;
  buffer >> dr;
  buffer >> dw;
  buffer >> d1mr;
  buffer >> d1mw;

  this->dr = to_int(dr);
  this->dw = to_int(dw);
  this->d1mr = to_int(d1mr);
  this->d1mw = to_int(d1mw);
}

int Parser::to_int(const string& s) {
  char *temp = new char[s.size() + 1];
  char *p = temp;
  for (unsigned int i = 0; i < s.size(); ++i) {
    if (s[i] != ',') {
      *p = s[i];
      ++p;
    }
  }
  *p = '\0';
  int n = atoi(temp);
  delete temp;
  return n;
}

int Parser::get_dw() const {
  return this->dw;
}

int Parser::get_d1mw() const {
  return this->d1mw;
}

int Parser::get_dw_ciclo() const {
  return this->dw_ciclo;
}

int Parser::get_d1mw_ciclo() const {
  return this->d1mw_ciclo;
}

